package com.qbw.app.module.vehicle.holder;

import android.animation.ValueAnimator;
import android.content.Context;
import androidx.databinding.ViewDataBinding;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;

import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.lib.util.ResUtil;
import com.lib.util.ScreenUtil;
import com.lib.util.StringUtil;
import com.qbw.app.Constant;
import com.qbw.app.R;
import com.qbw.app.databinding.VehicleHolderTravelDetailMapBinding;
import com.qbw.app.manager.MapManager;
import com.qbw.app.model.Travel;
import com.qbw.app.model.TravelGps;
import com.qbw.app.model.Warning;
import com.qbw.app.module.common.util.Gps;
import com.qbw.app.module.common.util.PositionUtil;
import com.qbw.app.module.vehicle.VehicleDataBindingAdapter;
import com.qbw.core.base.BaseHolder;
import com.qbw.l.L;
import com.qbw.log.XLog;
import com.qbw.spm.P;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import static com.qbw.app.Constant.KEY_MAP;
import static com.qbw.app.Constant.MAP_BAIDU;
import static com.qbw.app.Constant.MAP_DEFAULT;
import static com.qbw.app.Constant.MAP_GOOGLE;

/**
 * @author QBW
 * @date 2019-09-07
 */
public class VehicleTravelDetailMapHolder extends BaseHolder<VehicleTravelDetailMapHolder.Data, VehicleHolderTravelDetailMapBinding> implements OnMapReadyCallback {

    private Handler mHandler = new Handler();
    private boolean mUseBaidu = MAP_BAIDU.equals(P.getString(KEY_MAP, MAP_DEFAULT));
    private GoogleMap mGoogleMap;
    private int mTravelProgress;
    private boolean mNeedShowTravel;
    //private ShowTrailThread mTrailThread;
    private ValueAnimator mTrailValueAnimator;
    private Overlay mOverlayBaidu;
    private Marker mMarkerGoogle;
    private InfoWindow mBaiduInfoWindow;
    private Marker mGoogleMarkerInfoWindow;

    public VehicleTravelDetailMapHolder(Context context, ViewGroup viewParent) {
        super(context, R.layout.vehicle_holder_travel_detail_map, viewParent);
        initMap();
    }

    public VehicleTravelDetailMapHolder(Context context, ViewDataBinding binding) {
        super(context, binding);
        initMap();
    }

    @Override
    public void bindData(int position, Data data) {
        super.bindData(position, data);
        if (!data.mInited) {
            mData.mInited = true;
            //initMap();
            showTravel();
        }
    }

    private void initMap() {
        /*String map = P.getString(KEY_MAP, MAP_DEFAULT);
        mUseBaidu = MAP_BAIDU.equals(map);*/
        if (mUseBaidu) {
            mBinding.googleMapView.setVisibility(View.GONE);
            initBaidu();
        } else {
            mBinding.bmapView.setVisibility(View.GONE);
            initGoogle();
        }
    }

    private void initBaidu() {
        mBinding.bmapView.setVisibility(View.VISIBLE);
        mBinding.bmapView.showScaleControl(false);
        mBinding.bmapView.showZoomControls(false);

        BaiduMap map = mBinding.bmapView.getMap();
        map.setMyLocationEnabled(true);
        map.setMyLocationConfiguration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL,
                                                                   true,
                                                                   BitmapDescriptorFactory.fromResource(
                                                                           R.drawable.travel_offline)));
        //map.setOnMapClickListener(mBadiuMapClickListener);
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        map.setMapStatus(msu);

        //mLocationClient = new LocationClient(getApplicationContext());
        LocationClientOption option = new LocationClientOption();

        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，设置定位模式，默认高精度
        //LocationMode.Hight_Accuracy：高精度；
        //LocationMode. Battery_Saving：低功耗；
        //LocationMode. Device_Sensors：仅使用设备；

        option.setCoorType("bd09ll");
        //可选，设置返回经纬度坐标类型，默认gcj02
        //gcj02：国测局坐标；
        //bd09ll：百度经纬度坐标；
        //bd09：百度墨卡托坐标；
        //海外地区定位，无需设置坐标类型，统一返回wgs84类型坐标

        option.setScanSpan(1000);
        //可选，设置发起定位请求的间隔，int类型，单位ms
        //如果设置为0，则代表单次定位，即仅定位一次，默认为0
        //如果设置非0，需设置1000ms以上才有效

        option.setOpenGps(true);
        //可选，设置是否使用gps，默认false
        //使用高精度和仅用设备两种定位模式的，参数必须设置为true

        option.setLocationNotify(true);
        //可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false

        option.setIgnoreKillProcess(false);
        //可选，定位SDK内部是一个service，并放到了独立进程。
        //设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)

        option.SetIgnoreCacheException(false);
        //可选，设置是否收集Crash信息，默认收集，即参数为false

        option.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选，7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前WiFi是否超出有效期，若超出有效期，会先重新扫描WiFi，然后定位

        option.setEnableSimulateGps(false);
        //可选，设置是否需要过滤GPS仿真结果，默认需要，即参数为false

        //mLocationClient.setLocOption(option);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明

        //mLocationClient.registerLocationListener(mBaiduLocationListener = new
        // ElecAreaAddActivity.MyBaiduLocationListener());

        //mLocationClient.start();
        //mLocationClient.requestLocation();
        //showTravel();

        mBinding.bmapView.getMap().setOnMarkerClickListener(marker -> {
            Bundle bundle = marker.getExtraInfo();
            if (bundle != null) {
                if (mBaiduInfoWindow != null) {
                    mBinding.bmapView.getMap()
                            .hideInfoWindow();
                    mBaiduInfoWindow = null;
                    return true;
                }
                Serializable extra = bundle.getSerializable(Constant.KEY_TAG);
                if (extra instanceof Warning) {
                    Warning warning = (Warning) extra;
                    VehicleMarderHolder marderHolder = new VehicleMarderHolder(mContext, null);
                    marderHolder.bindData(0,
                                          new VehicleMarderHolder.Data(warning.getAlarmName(),
                                                                       VehicleDataBindingAdapter.getVehicleTime(
                                                                               warning.getStartTime(), true)));
                    InfoWindow infoWindow = new InfoWindow(BitmapDescriptorFactory.fromView(
                            marderHolder.itemView),
                                                           marker.getPosition(),
                                                           -ScreenUtil.dp2px(mContext, 50),
                                                           () -> {mBinding.bmapView.getMap()
                                                                                  .hideInfoWindow();
                                                               mBaiduInfoWindow = null;});
                    mBaiduInfoWindow = infoWindow;
                    mBinding.bmapView.getMap().showInfoWindow(infoWindow);
                }
            }
            return true;
        });
    }

    private void baiduAnimateToPosition(double lat, double lon) {
        Gps gps = PositionUtil.gps84_to_bd09_byBaiduSdk(lat, lon);
        MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(new LatLng(gps.getWgLat(),
                                                                             gps.getWgLon()));
        // 移动到某经纬度
        mBinding.bmapView.getMap().animateMapStatus(update);
    }

    private Overlay baiduAnimateAndAddMarker(double latitude,
                                             double longitude,
                                             int positionDrawableRes) {
        return baiduAnimateAndAddMarker(false, latitude, longitude, positionDrawableRes, null);
    }

    private Overlay baiduAnimateAndAddMarker(boolean animateToPosition,
                                             double latitude,
                                             double longitude,
                                             int positionDrawableRes,
                                             Serializable extra) {
        return baiduAnimateAndAddMarker(animateToPosition, latitude, longitude, positionDrawableRes, extra, -1);
    }

    /**
     * 移动到指定位置，并添加marker
     */
    private Overlay baiduAnimateAndAddMarker(boolean animateToPosition,
                                             double latitude,
                                             double longitude,
                                             int positionDrawableRes,
                                             Serializable extra, int zIndex) {
        if (animateToPosition) {
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(new LatLng(latitude,
                                                                                 longitude));
            // 移动到某经纬度
            mBinding.bmapView.getMap().animateMapStatus(update);
        }

        //添加marker
        Overlay overlay = mBinding.bmapView.getMap()
                                           .addOverlay(new com.baidu.mapapi.map.MarkerOptions().position(
                                                   new LatLng(latitude, longitude))
                                                                                               .icon(BitmapDescriptorFactory
                                                                                                             .fromResource(
                                                                                                                     positionDrawableRes)));
        overlay.setZIndex(zIndex >= 0 ? zIndex : 3);
        if (extra != null) {
            Bundle bundle = new Bundle();
            bundle.putSerializable(Constant.KEY_TAG, extra);
            overlay.setExtraInfo(bundle);
        }
        return overlay;
    }

    private void googleAnimateToPosition(double lat, double lon) {
        if (mGoogleMap == null) {
            XLog.e("mGoogleMap == null");
            return;
        }
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(new com.google.android.gms.maps.model.LatLng(
                lat,
                lon));
        mGoogleMap.moveCamera(cameraUpdate);
    }

    private com.google.android.gms.maps.model.Marker googleAnimateAndAddMarker(double latitude,
                                                                               double longitude,
                                                                               int positionDrawableRes) {
        return googleAnimateAndAddMarker(true, latitude, longitude, positionDrawableRes, null);
    }

    private com.google.android.gms.maps.model.Marker googleAnimateAndAddMarker(boolean animateToPosition,
                                                                               double latitude,
                                                                               double longitude,
                                                                               int positionDrawableRes,
                                                                               Serializable extra) {
        return googleAnimateAndAddMarker(animateToPosition,
                latitude,
                longitude,
                positionDrawableRes,
                extra, -1);
    }

    private com.google.android.gms.maps.model.Marker googleAnimateAndAddMarker(boolean animateToPosition,
                                                                               double latitude,
                                                                               double longitude,
                                                                               int positionDrawableRes,
                                                                               Serializable extra, int zIndex) {
        Gps _gps = /*PositionUtil.gps84_To_Gcj02(latitude, longitude)*/new Gps(latitude, longitude);
        if (animateToPosition) {
            // 移动到某经纬度
            CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(new com.google.android.gms.maps.model.LatLng(
                    _gps.getWgLat(),
                    _gps.getWgLon()));
            mGoogleMap.moveCamera(cameraUpdate);
        }

        //添加marker

        com.google.android.gms.maps.model.Marker marker = mGoogleMap.addMarker(new MarkerOptions().icon(
                com.google.android.gms.maps.model.BitmapDescriptorFactory.fromResource(
                        positionDrawableRes))
                                                                                                  .position(
                                                                                                          new com.google.android.gms.maps.model.LatLng(
                                                                                                                  _gps.getWgLat(),
                                                                                                                  _gps.getWgLon())));
        marker.setTag(extra);
        marker.setZIndex(zIndex >= 0 ? zIndex : 3);
        return marker;
    }

    private void initGoogle() {
        mBinding.googleMapView.setVisibility(View.VISIBLE);
        mBinding.googleMapView.onCreate(null);
        mBinding.googleMapView.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.getUiSettings().setCompassEnabled(false);
        CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(15);
        mGoogleMap.moveCamera(cameraUpdate);
        if (mNeedShowTravel) {
            mNeedShowTravel = false;
            showTravel();
        }
        onResume();
        mGoogleMap.setInfoWindowAdapter(new GoogleInfoAdapter(mContext));
        mGoogleMap.setOnInfoWindowCloseListener(new GoogleMap.OnInfoWindowCloseListener() {
            @Override
            public void onInfoWindowClose(Marker marker) {
                // 点击地图时触发（没有办法可以屏蔽），当主动调用hideInfoWindow时不会触发此方法
                // 事件传递顺序OnInfoWindowClose-->OnMapClickListener
                // 不能在这里调用showInfoWindow，不起作用
            }
        });
        mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                if (marker.getTag() != null) {
                    // 一定要设置setOnMapClickListener始终显示，要不这里mGoogleMarkerInfoWindow一直为null
                    if (mGoogleMarkerInfoWindow != null) {
                        mGoogleMarkerInfoWindow.hideInfoWindow();
                        mGoogleMarkerInfoWindow = null;
                    } else {
                        mGoogleMarkerInfoWindow = marker;
                        marker.showInfoWindow();
                    }
                }
                // 要返回true，否则右下角会有简化图标
                return true;
            }
        });
        mGoogleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(Marker marker) {
                if (mGoogleMarkerInfoWindow != null) {
                    mGoogleMarkerInfoWindow.hideInfoWindow();
                    mGoogleMarkerInfoWindow = null;
                }
            }
        });
        mGoogleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(com.google.android.gms.maps.model.LatLng latLng) {
                if (mGoogleMarkerInfoWindow != null) {
                    mGoogleMarkerInfoWindow.showInfoWindow();
                }
            }
        });
    }

    private static class GoogleInfoAdapter implements GoogleMap.InfoWindowAdapter {

        private Context mContext;

        public GoogleInfoAdapter(Context context) {
            mContext = context;
        }

        @Override
        public View getInfoWindow(Marker marker) {
            if (marker.getTag() instanceof Warning) {
                Warning warning = (Warning) marker.getTag();
                VehicleMarderHolder marderHolder = new VehicleMarderHolder(mContext, null);
                marderHolder.bindData(0,
                                      new VehicleMarderHolder.Data(warning.getAlarmName(),
                                                                   VehicleDataBindingAdapter.getVehicleTime(
                                                                           warning.getStartTime(), true)));
                return marderHolder.itemView;
            }
            return null;
        }

        @Override
        public View getInfoContents(Marker marker) {
            return null;
        }
    }

    public void updateAlarm(Warning.ResponseList alarmResponse) {
        if (alarmResponse.size() > 0) {
            double lat;
            double lng;
            int did;
            boolean animateToPosition = mData.gpsSize() <= 0;
            int size = alarmResponse.size();
            for (int i = size - 1; i >= 0; i--) {
                Warning warning = alarmResponse.getData().get(i);
                lat = StringUtil.numberDouble(warning.getStartLatitude());
                lng = StringUtil.numberDouble(warning.getStartLongitude());
                if (lat == 0 && lng == 0) {
                    continue;
                }
                did = getJiDrawable(warning.getAlarmId());
                if (did == 0) {
                    continue;
                }
                if (MapManager.getInstance().isUseBaidu()) {
                    Gps gps = PositionUtil.gps84_to_bd09_byBaiduSdk(lat, lng);
                    baiduAnimateAndAddMarker(animateToPosition,
                                             gps.getWgLat(),
                                             gps.getWgLon(),
                                             did,
                                             warning);
                } else {
                    Gps gps = PositionUtil.gps84_To_Gcj02(lat, lng);
                    googleAnimateAndAddMarker(animateToPosition,
                                              gps.getWgLat(),
                                              gps.getWgLon(),
                                              did,
                                              warning);
                }
            }
        }
    }

    private int getJiDrawable(long alarmId) {
        int d = 0;
        if (alarmId == Constant.EVENT_INCREASE_SPEED) {
            d = R.drawable.ji_add;
        } else if (alarmId == Constant.EVENT_REDUCE_SPEED) {
            d = R.drawable.ji_minus;
        } else if (alarmId == Constant.EVENT_TURN_HURRY) {
            d = R.drawable.ji_turn;
        }
        return d;
        //return VehicleDataBindingAdapter.getAlarmIdImage(alarmId,0);
    }

    public void updateTravel(int progress) {
        if (mData == null || !mData.mInited) {
            return;
        }
        if (progress < 0 || progress >= mData.gpsSize()) {
            return;
        }
        //mUpdateByManual = true;
        mTravelProgress = progress;
        showNowGpsUiThread(mData.gpsSize() - 1 - progress);
    }

    public void pauseTrailAnimator() {

    }

    /**
     * 显示进度轨迹动画
     */
    public boolean showTrailAnimator() {
        /*if (mTrailThread != null) {
            mTrailThread.setEnd(false);
        }
        mTrailThread = new ShowTrailThread(mTravelProgress, this);
        mTrailThread.start();*/
        if (mData.gpsSize() <= 1) {
            L.GL.w("show gps animation need more than 1 gps point!!!");
            return false;
        }
        /*if (mTrailValueAnimator != null) {
            mTrailValueAnimator.cancel();
        }
        mTrailValueAnimator = ValueAnimator.ofInt(1, *//*mTravelProgress*//*mData.gpsSize());
        mTrailValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                showNowGps(mData.gpsSize() - 1 - value);
            }
        });
        mTrailValueAnimator.setInterpolator(new LinearInterpolator());
        mTrailValueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                onEnd(false);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        //0.3秒一个点
        int second = mData.gpsSize() / 100;
        if (second < 2) {
            second = 2;
        } else if (second > 10) {
            second = 10;
        }
        mTrailValueAnimator.setDuration(second * 1000);
        mTrailValueAnimator.start();*/
        return true;
    }

    public void updateTravelEnd() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (MapManager.getInstance().isUseBaidu()) {
                    if (mOverlayBaidu != null) {
                        mOverlayBaidu.remove();
                    }
                } else {
                    if (mMarkerGoogle != null) {
                        mMarkerGoogle.remove();
                    }
                }
            }
        }, 600);
    }

    private void showNowGpsUiThread(int index) {
        mHandler.post(() -> showNowGps(index));
    }

    private void onShowNowGps(TravelGps gps) {
        if (mContext instanceof Listener) {
            ((Listener) mContext).onMapTrailDrawing(gps);
        }
    }

    private void showNowGps(int gpsIndex) {
        if (gpsIndex < 0 || gpsIndex >= mData.gpsSize()) {
            L.GL.e("This code should not exec!!!");
            return;
        }
        TravelGps gps = mData.mTravelGps.get(gpsIndex);
        onShowNowGps(gps);
        if (MapManager.getInstance().isUseBaidu()) {
            if (mOverlayBaidu != null) {
                mOverlayBaidu.remove();
            }
            mOverlayBaidu = baiduAnimateAndAddMarker(false,
                                                     gps.getLatitude(),
                                                     gps.getLongitude(),
                                                     R.drawable.travel_location,
                                                     null, 10);
        } else {
            if (mMarkerGoogle != null) {
                mMarkerGoogle.remove();
            }
            mMarkerGoogle = googleAnimateAndAddMarker(false,
                                                      gps.getLatitude(),
                                                      gps.getLongitude(),
                                                      R.drawable.travel_location, null, 10);
        }
    }

    public boolean isShowingTrail() {
        return mTrailValueAnimator != null && mTrailValueAnimator.isStarted();
    }

    /*private static class ShowTrailThread extends Thread {
        private int mNumber;
        private boolean mEnd;
        private WeakReference<VehicleTravelDetailMapHolder> mWrHolder;

        public ShowTrailThread(int number, VehicleTravelDetailMapHolder holder) {
            mNumber = number;
            mWrHolder = new WeakReference<>(holder);
        }


        @Override
        public void run() {
            super.run();
            VehicleTravelDetailMapHolder holder = null;
            for (int i = 0; i < mNumber; i++) {
                holder = mWrHolder.get();
                if (mEnd) {
                    if (holder != null) {
                        holder.onEnd(true);
                    }
                    break;
                }
                if (holder != null) {
                    holder.showNowGpsUiThread(holder.mData.gpsSize() - 1 - i);
                }
                try {
                    sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            mEnd = true;
            if (holder != null) {
                holder.onEnd(false);
            }
        }

        public void setEnd(boolean end) {
            mEnd = end;
        }
    }*/

    private void onEnd(boolean manual) {
        if (mContext instanceof Listener) {
            mHandler.post(() -> ((Listener) mContext).onMapTrailEnd(manual));
        }
    }

    private Travel getTravel() {
        if (mContext instanceof Listener) {
            return ((Listener) mContext).onGetTravelData();
        }
        return null;
    }

    private void showTravel() {
        int gpsSize = mData.gpsSize();
        L.GL.d("gpsSize[%d]", gpsSize);
        if (gpsSize <= 0) {
            L.GL.w("no gps data");
            Travel travel = getTravel();
            Travel.Point point = null;
            if (travel.getStartPoint() != null && travel.getStartPoint().isPointValid()) {
                point = travel.getStartPoint();
            } else if (travel.getEndPoint() != null && travel.getEndPoint().isPointValid()) {
                point = travel.getEndPoint();
            }
            if (point == null) {
                if (MapManager.getInstance().isUseBaidu()) {
                    //do nothing
                } else {
                    CameraUpdate cameraUpdate = CameraUpdateFactory.zoomTo(1);
                    mGoogleMap.moveCamera(cameraUpdate);
                }
            } else {
                if (MapManager.getInstance().isUseBaidu()) {
                    Gps gps = PositionUtil.gps84_to_bd09_byBaiduSdk(point.getLatitude(),
                                                                    point.getLongitude());
                    baiduAnimateAndAddMarker(true,
                                             gps.getWgLat(),
                                             gps.getWgLon(),
                                             R.drawable.travel_start,
                                             null);
                } else {
                    Gps gps = PositionUtil.gps84_To_Gcj02(point.getLatitude(),
                                                          point.getLongitude());
                    googleAnimateAndAddMarker(gps.getWgLat(),
                                              gps.getWgLon(),
                                              R.drawable.travel_start);
                }
            }
            return;
        }
        String map = P.getString(KEY_MAP, MAP_DEFAULT);
        if (map.equals(MAP_BAIDU)) {
            mBinding.bmapView.getMap().clear();
            if (gpsSize == 1) {
                TravelGps gps = mData.mTravelGps.get(0);
                L.GL.w("on gps[%f, %f]", gps.getLatitude(), gps.getLongitude());
                baiduAnimateAndAddMarker(true,
                                         gps.getLatitude(),
                                         gps.getLongitude(),
                                         R.drawable.travel_start,
                                         null);
            } else {
                TravelGps startGps = mData.mTravelGps.get(gpsSize - 1);
                mBinding.bmapView.getMap()
                                 .addOverlay(new com.baidu.mapapi.map.MarkerOptions().icon(
                                         BitmapDescriptorFactory.fromResource(R.drawable.travel_start))
                                                                                     .position(new LatLng(
                                                                                             startGps.getLatitude(),
                                                                                             startGps.getLongitude())))
                                 .setZIndex(6);
                TravelGps endGps = mData.mTravelGps.get(0);
                mBinding.bmapView.getMap()
                                 .addOverlay(new com.baidu.mapapi.map.MarkerOptions().icon(
                                         BitmapDescriptorFactory.fromResource(R.drawable.travel_end))
                                                                                     .position(new LatLng(
                                                                                             endGps.getLatitude(),
                                                                                             endGps.getLongitude())))
                                 .setZIndex(4);


                TravelGps travelGps;
                com.baidu.mapapi.model.LatLngBounds.Builder builder = new com.baidu.mapapi.model.LatLngBounds.Builder();
                List<LatLng> latLngs = new ArrayList<>();
                //int seekProgress = gpsSize - mTravelProgress;
                for (int i = gpsSize - 1; i >= 0; i--) {
                    travelGps = mData.mTravelGps.get(i);
                    //经纬度都是0的舍弃
                    if (travelGps.getLatitude() == 0f && travelGps.getLongitude() == 0f) {
                        continue;
                    }
                    //if (i >= seekProgress) {
                    latLngs.add(new LatLng(travelGps.getLatitude(), travelGps.getLongitude()));
                    //}
                    builder.include(new LatLng(travelGps.getLatitude(), travelGps.getLongitude()));
                }

                L.GL.e("here1，latLngs[%d],gpsSize[%d]", latLngs.size(), gpsSize);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        L.GL.e("her3");
                        mBinding.bmapView.getMap()
                                         .animateMapStatus(MapStatusUpdateFactory.newLatLngBounds(
                                                 builder.build(),
                                                 mBinding.bmapView.getWidth() - 100,
                                                 mBinding.bmapView.getHeight() - 260));

                        L.GL.d("latLngs[%d]", latLngs.size());
                        if (latLngs.size() >= 2) {
                            OverlayOptions ooPolyline = new PolylineOptions().width(Constant.TRAVEL_LINE_WIDTH)
                                                                             .color(ResUtil.getColor(
                                                                                     R.color.travel_line_color))
                                                                             .points(latLngs);
                            mBinding.bmapView.getMap().addOverlay(ooPolyline);
                        }
                    }
                }, 500);
            }
        } else if (map.equals(MAP_GOOGLE)) {
            if (mGoogleMap == null) {
                mNeedShowTravel = true;
                return;
            }
            mGoogleMap.clear();
            if (gpsSize == 1) {
                TravelGps gps = mData.mTravelGps.get(0);
                googleAnimateAndAddMarker(gps.getLatitude(),
                                          gps.getLongitude(),
                                          R.drawable.travel_start);
            } else {
                TravelGps startGps = mData.mTravelGps.get(gpsSize - 1);
                TravelGps endGps = mData.mTravelGps.get(0);
                mGoogleMap.addMarker(new com.google.android.gms.maps.model.MarkerOptions().icon(com.google.android.gms.maps.model.BitmapDescriptorFactory
                                                                                                        .fromResource(
                                                                                                                R.drawable.travel_start))
                                                                                          .position(
                                                                                                  new com.google.android.gms.maps.model.LatLng(
                                                                                                          startGps.getLatitude(),
                                                                                                          startGps.getLongitude())))
                          .setZIndex(6);
                mGoogleMap.addMarker(new com.google.android.gms.maps.model.MarkerOptions().icon(com.google.android.gms.maps.model.BitmapDescriptorFactory
                                                                                                        .fromResource(
                                                                                                                R.drawable.travel_end))
                                                                                          .position(
                                                                                                  new com.google.android.gms.maps.model.LatLng(
                                                                                                          endGps.getLatitude(),
                                                                                                          endGps.getLongitude())))
                          .setZIndex(4);

                TravelGps travelGps;
                com.google.android.gms.maps.model.PolylineOptions polylineOptions = new com.google.android.gms.maps.model.PolylineOptions();
                for (int i = gpsSize - 1; i >= 0; i--) {
                    travelGps = mData.mTravelGps.get(i);
                    //经纬度都是0的舍弃
                    if (travelGps.getLatitude() == 0f && travelGps.getLongitude() == 0f) {
                        continue;
                    }
                    polylineOptions.add(new com.google.android.gms.maps.model.LatLng(travelGps.getLatitude(),
                                                                                     travelGps.getLongitude()));
                }
                polylineOptions.width(Constant.TRAVEL_LINE_WIDTH)
                               .color(ResUtil.getColor(R.color.travel_line_color));
                mGoogleMap.addPolyline(polylineOptions);

                LatLngBounds.Builder builder = new LatLngBounds.Builder();
                builder.include(new com.google.android.gms.maps.model.LatLng(startGps.getLatitude(),
                                                                             startGps.getLongitude()));
                builder.include(new com.google.android.gms.maps.model.LatLng(endGps.getLatitude(),
                                                                             endGps.getLongitude()));
                /*if (mBinding.googleMapView.getWidth() > 260) {
                    CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(builder.build(), 260);
                    mGoogleMap.moveCamera(cu);
                } else {
                    mHandler.postDelayed(() -> {
                        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(builder.build(),
                                                                              mBinding.googleMapView
                                                                                      .getWidth() > 260 ? 260 : 0);
                        mGoogleMap.moveCamera(cu);
                    }, 500);
                }*/
                if (!googleMoveCamera(builder)) {
                    mHandler.postDelayed(() -> {
                        if (!googleMoveCamera(builder)) {
                            mHandler.postDelayed(() -> {
                                googleMoveCamera(builder);
                            }, 500);
                        }
                    }, 500);
                }
            }
        }
    }

    private boolean googleMoveCamera(LatLngBounds.Builder builder) {
        boolean b = true;
        try {
            CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(builder.build(), 260);
            mGoogleMap.moveCamera(cu);
        } catch (Exception e) {
            e.printStackTrace();
            L.GL.w(e);
            b = false;
        }
        return b;
    }

    public void onResume() {
        if (mUseBaidu) {
            if (mBinding.bmapView == null) {
                return;
            }
            mBinding.bmapView.onResume();
        } else {
            if (mBinding.googleMapView == null || mGoogleMap == null) {
                return;
            }
            mBinding.googleMapView.onResume();
        }
    }

    public void onPause() {
        if (mUseBaidu) {
            if (mBinding.bmapView == null) {
                return;
            }
            mBinding.bmapView.onPause();
        } else {
            if (mBinding.googleMapView == null) {
                return;
            }
            mBinding.googleMapView.onPause();
        }
    }

    public void onDestroy() {
        if (mUseBaidu) {
            if (mBinding.bmapView == null) {
                return;
            }
            mBinding.bmapView.onDestroy();
        } else {
            if (mBinding.googleMapView == null) {
                return;
            }
            mBinding.googleMapView.onDestroy();
        }
    }

    public static class Data {
        private boolean mInited = false;
        private List<TravelGps> mTravelGps;

        public Data(List<TravelGps> travelGps) {
            mTravelGps = travelGps;
        }

        public int gpsSize() {
            return mTravelGps == null ? 0 : mTravelGps.size();
        }
    }

    public interface Listener {
        void onMapTrailEnd(boolean manual);

        void onMapTrailDrawing(TravelGps gps);

        Travel onGetTravelData();
    }
}
